home *** CD-ROM | disk | FTP | other *** search
- /* termiosmodule.c -- POSIX terminal I/O module implementation. */
-
- #include <Python.h>
-
- #define PyInit_termios inittermios
-
- #include <termios.h>
-
- #define BAD "bad termios argument"
-
- static PyObject *TermiosError;
-
- /* termios = tcgetattr(fd)
- termios is
- [iflag, oflag, cflag, lflag, ispeed, ospeed, [cc[0], ..., cc[NCCS]]]
-
- Return the attributes of the terminal device. */
-
- static PyObject *
- termios_tcgetattr(self, args)
- PyObject *self;
- PyObject *args;
- {
- int fd;
- struct termios mode;
- PyObject *cc;
- speed_t ispeed, ospeed;
- PyObject *v;
- int i;
- char ch;
-
- if (!PyArg_Parse(args, "i", &fd))
- return NULL;
-
- if (tcgetattr(fd, &mode) == -1)
- PyErr_SetFromErrno(TermiosError);
-
- ispeed = cfgetispeed(&mode);
- ospeed = cfgetospeed(&mode);
-
- cc = PyList_New(NCCS);
- if (cc == NULL)
- return NULL;
- for (i = 0; i < NCCS; i++) {
- ch = (char)mode.c_cc[i];
- v = PyString_FromStringAndSize(&ch, 1);
- if (v == NULL)
- return NULL;
- PyList_SetItem(cc, i, v);
- }
-
- /* Convert the MIN and TIME slots to integer. On some systems, the
- MIN and TIME slots are the same as the EOF and EOL slots. So we
- only do this in noncanonical input mode. */
- if (mode.c_lflag & ICANON == 0) {
- v = PyInt_FromLong((long)mode.c_cc[VMIN]);
- if (v == NULL)
- return NULL;
- PyList_SetItem(cc, VMIN, v);
- v = PyInt_FromLong((long)mode.c_cc[VTIME]);
- if (v == NULL)
- return NULL;
- PyList_SetItem(cc, VTIME, v);
- }
-
- v = PyList_New(7);
- PyList_SetItem(v, 0, PyInt_FromLong((long)mode.c_iflag));
- PyList_SetItem(v, 1, PyInt_FromLong((long)mode.c_oflag));
- PyList_SetItem(v, 2, PyInt_FromLong((long)mode.c_cflag));
- PyList_SetItem(v, 3, PyInt_FromLong((long)mode.c_lflag));
- PyList_SetItem(v, 4, PyInt_FromLong((long)ispeed));
- PyList_SetItem(v, 5, PyInt_FromLong((long)ospeed));
- PyList_SetItem(v, 6, cc);
-
- return v;
- }
-
- /* tcsetattr(fd, when, termios)
- Set the attributes of the terminal device. */
-
- static PyObject *
- termios_tcsetattr(self, args)
- PyObject *self;
- PyObject *args;
- {
- int fd, when;
- struct termios mode;
- speed_t ispeed, ospeed;
- PyObject *term, *cc, *v;
- int i;
-
- if (!PyArg_Parse(args, "(iiO)", &fd, &when, &term))
- return NULL;
- if (!PyList_Check(term) || PyList_Size(term) != 7) {
- PyErr_SetString(PyExc_TypeError, BAD);
- return NULL;
- }
- for (i = 0; i < 6; i++)
- if (!PyInt_Check(PyList_GetItem(term, i))) {
- PyErr_SetString(PyExc_TypeError, BAD);
- return NULL;
- }
-
- mode.c_iflag = (tcflag_t) PyInt_AsLong(PyList_GetItem(term, 0));
- mode.c_oflag = (tcflag_t) PyInt_AsLong(PyList_GetItem(term, 1));
- mode.c_cflag = (tcflag_t) PyInt_AsLong(PyList_GetItem(term, 2));
- mode.c_lflag = (tcflag_t) PyInt_AsLong(PyList_GetItem(term, 3));
- ispeed = (speed_t) PyInt_AsLong(PyList_GetItem(term, 4));
- ospeed = (speed_t) PyInt_AsLong(PyList_GetItem(term, 5));
- cc = PyList_GetItem(term, 6);
-
- if (!PyList_Check(cc) || PyList_Size(cc) != NCCS) {
- PyErr_SetString(PyExc_TypeError, BAD);
- return NULL;
- }
-
- for (i = 0; i < NCCS; i++) {
- v = PyList_GetItem(cc, i);
- if (PyString_Check(v) && PyString_Size(v) == 1)
- mode.c_cc[i] = (cc_t) * PyString_AsString(v);
- else if (PyInt_Check(v))
- mode.c_cc[i] = (cc_t) PyInt_AsLong(v);
- else {
- PyErr_SetString(PyExc_TypeError, BAD);
- return NULL;
- }
- }
-
- if (cfsetispeed(&mode, (speed_t) ispeed) == -1)
- PyErr_SetFromErrno(TermiosError);
- if (cfsetospeed(&mode, (speed_t) ospeed) == -1)
- PyErr_SetFromErrno(TermiosError);
- if (tcsetattr(fd, when, &mode) == -1)
- PyErr_SetFromErrno(TermiosError);
-
- Py_INCREF(Py_None);
- return Py_None;
- }
-
- /* tcsendbreak(fd, duration)
- Generate a break condition. */
-
- static PyObject *
- termios_tcsendbreak(self, args)
- PyObject *self;
- PyObject *args;
- {
- int fd, duration;
-
- if (!PyArg_Parse(args, "(ii)", &fd, &duration))
- return NULL;
- if (tcsendbreak(fd, duration) == -1)
- PyErr_SetFromErrno(TermiosError);
-
- Py_INCREF(Py_None);
- return Py_None;
- }
-
- /* tcdrain(fd)
- Wait until all queued output to the terminal has been
- transmitted. */
-
- static PyObject *
- termios_tcdrain(self, args)
- PyObject *self;
- PyObject *args;
- {
- int fd;
-
- if (!PyArg_Parse(args, "i", &fd))
- return NULL;
- if (tcdrain(fd) == -1)
- PyErr_SetFromErrno(TermiosError);
-
- Py_INCREF(Py_None);
- return Py_None;
- }
-
- /* tcflush(fd, queue)
- Clear the input and/or output queues associated with
- the terminal. */
-
- static PyObject *
- termios_tcflush(self, args)
- PyObject *self;
- PyObject *args;
- {
- int fd, queue;
-
- if (!PyArg_Parse(args, "(ii)", &fd, &queue))
- return NULL;
- if (tcflush(fd, queue) == -1)
- PyErr_SetFromErrno(TermiosError);
-
- Py_INCREF(Py_None);
- return Py_None;
- }
-
- /* tcflow(fd, action)
- Perform operations relating to XON/XOFF flow control on
- the terminal. */
-
- static PyObject *
- termios_tcflow(self, args)
- PyObject *self;
- PyObject *args;
- {
- int fd, action;
-
- if (!PyArg_Parse(args, "(ii)", &fd, &action))
- return NULL;
- if (tcflow(fd, action) == -1)
- PyErr_SetFromErrno(TermiosError);
-
- Py_INCREF(Py_None);
- return Py_None;
- }
-
- static PyMethodDef termios_methods[] =
- {
- {"tcgetattr", termios_tcgetattr},
- {"tcsetattr", termios_tcsetattr},
- {"tcsendbreak", termios_tcsendbreak},
- {"tcdrain", termios_tcdrain},
- {"tcflush", termios_tcflush},
- {"tcflow", termios_tcflow},
- {NULL, NULL}
- };
-
- void
- PyInit_termios()
- {
- PyObject *m, *d;
-
- m = Py_InitModule("termios", termios_methods);
-
- d = PyModule_GetDict(m);
- TermiosError = Py_BuildValue("s", "termios.error");
- PyDict_SetItemString(d, "error", TermiosError);
-
- if (PyErr_Occurred())
- Py_FatalError("can't initialize module termios");
- }
-